Project Group - 15¶

Members: Sören Burghardt (5861012), Sarah Blanc (5854830), Allan Guzmán (5718619), Lars van den Berg (5626668) & Simon Schreders (5878845).

Research Objective¶

What are the effects on aviation that COVID-19 caused at the Amsterdam Schiphol Airport and its most frequented destinations for freight and passenger transport?

When COVID-19 became a global pandemic in 2020, the containments plunged the global economy into an unprecedented recession. The magnitude of the economic shock was such that it resulted in unrecognisable data and a "data fog" that made it difficult to interpret and, more importantly, to predict. The last two years have been extraordinary, both for global economy and the humanity. While the COVID-19 pandemic now appears to be under control thanks to vaccination programmes, parts of the global economy are not yet fully recovered. As a result of the protective travel restrictions, the aviation sector has been hit harder than many others industries. In this project, our aim was to observe the impacts that covid has had on aviation and in particular, the impacts on Amsterdam Schiphol Airport and its most frequented destinations. This from the perspective of passenger and freight transport.

This research question is answered by answering similiar sub-research questions:

  1. What is the overall passenger and cargo transport from Amsterdam Schiphol Airport 2019 and 2021?
  2. What is the top 5 of frequent destinations for passenger transport from Amsterdam Schiphol Airport (2019)?
  3. What is the top 5 of frequent destinations for cargo transport from Amsterdam Schiphol Airport (2019)?
  4. What are the volumes of these top 5's in the last 20 years?
  5. How did the COVID-19 cases develop in these countries in the last two years?
  6. How did the vaccination rate for COVID-19 develop in these countries in the last two years?
  7. What impact did the COVID-19 cases have on the passenger transport from Amsterdam Schiphol Airport?
  8. What impact did the COVID-19 cases have on the cargo transport from Amsterdam Schiphol Airport?
  9. What impact did the vaccination rate have on the passenger transport at Amsterdam Schiphol Airport?
  10. What impact did the vaccination rate have on the cargo transport at Amsterdam Schiphol Airport?
  11. What is the impact of COVID-19 on the other Dutch airports?

Extra: Are there other effects caused by COVID-19 (China comparison)?

Contribution Statement¶

Sören: Background research, coding, conceptualisation, visualisation, data analysis, data modelling & reporting.

Sarah: Background research, coding, conceptualisation, visualisation, data analysis, data modelling & reporting.

Allan: Background research, coding, conceptualisation, visualisation, data analysis, data modelling & reporting.

Lars: Background research, coding, conceptualisation, visualisation, data analysis, data modelling & reporting.

Simon: Background research, coding, conceptualisation, visualisation, data analysis, data modelling & reporting.

Data Used¶

COVID-19 cases in the world (Our World in Data)

Flight data passengers (Eu Stat)

Flight data freight (EU Stat)

OD Data for Airport Amsterdam (EU Stat)

Flight data passengers & cargo Dutch airports (CBS)

Chinese data (Worldbank)

Data Pipeline¶

All the data for flights from Amsterdam Airport Schiphol (EHAM) were grouped by country. This way two top 5 were created for both the volume of cargo and mail and the passangers. The countries from these two top 5's and the Netherlands were used to filter the COVID-19 cases, using the amount of confirmed new cases per million in a country.

As a first step, we are going to import all the librairies that we will need.

In [1]:
import pandas as pd
import numpy as np
import plotly as plt

import math
import scipy

import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
import plotly.graph_objects as go

import geopandas as gpd

import plotly.io as pio
import plotly.graph_objects as go   
import country_converter as coco
from plotly.subplots import make_subplots

import plotly.io as pio
pio.renderers.default = "plotly_mimetype+notebook"
pd.options.mode.chained_assignment = None

1. What is the overall passenger and cargo transport at Amsterdam Schiphol Airport 2019 and 2021 ?¶

In [2]:
# Import datasets
cargo = pd.read_csv("Data_Sets/avia_gor_nl__custom_3564729_monthly_linear.csv")
passengers = pd.read_csv("Data_Sets/avia_par_nl__custom_3564728_monthly_linear.csv")

# COVID-19 dataset
filepath = 'Data_Sets/owid-covid-data.csv'
covid_data = pd.read_csv(filepath, delimiter=',')

# Importing the world geometry data from geopandas library
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
In [3]:
# Setting up special cleaning list
country_code_fix = {'EL':'GR','AN':'BQ'}

def codes_correction(df,ISO_2):
    # This function has a data frame and a ISO2 countries list and outputs the same 
    # dataframe adding a ISO3 code and the country name for each unique
    df[ISO_2] = df[ISO_2].replace(to_replace= country_code_fix)
    df['iso_3_country'] = coco.convert(names = df[ISO_2], to= 'ISO3')
    df['country_2_name'] = coco.convert(names = df[ISO_2], to= 'name_short')
    return df

def column_splitting(df):
    # This function has a data frame as an input with airport and country codes
    # and as an output the splitting of those codes 
    df[["airp_country_1","airp_code_1","airp_country_2","airp_code_2"]] = df.airp_pr.str.split("_",expand=True)
    df[["Year","Month"]] = df.TIME_PERIOD.str.split("-",expand=True)
    return df
In [4]:
# Calling the above defined function
passengers = column_splitting(passengers)
cargo = column_splitting(cargo)

# Set up datasets for visualisation 
# For passengers 
passengers_for_map = passengers.groupby(['Year','airp_country_2']).sum()
passengers_for_map_2019 = passengers_for_map.loc['2019',:].reset_index()
passengers_for_map_2021 = passengers_for_map.loc['2021',:].reset_index()
passengers_for_map_2019 = codes_correction(passengers_for_map_2019,'airp_country_2')
passengers_for_map_2021 = codes_correction(passengers_for_map_2021,'airp_country_2')

# For cargo 
cargo_for_map = cargo.groupby(['Year','airp_country_2']).sum()
cargo_for_map_2019 = cargo_for_map.loc['2019',:].reset_index()
cargo_for_map_2021 = cargo_for_map.loc['2021',:].reset_index()
cargo_for_map_2019 = codes_correction(cargo_for_map_2019,'airp_country_2')
cargo_for_map_2021 = codes_correction(cargo_for_map_2021,'airp_country_2')
In [5]:
# Defining visualisation labels
passenger_labels = {
    'OBS_VALUE':'Total passengers',
    'country_2_name': 'Country',
    'iso_3_country': 'Country code'
}
cargo_labels = {
    'country_2_name':'Country',
    'OBS_VALUE': 'Total cargo [tons]',
    'iso_3_country': 'Country code'
}
In [6]:
# Visualisation of passengers merged datasets in 2019
map_data_passengers_2019 = world.merge(passengers_for_map_2019,left_on = 'iso_a3', right_on = 'iso_3_country', how = 'left')

fig = px.choropleth(map_data_passengers_2019, hover_name = 'country_2_name',locations= 'iso_3_country', \
    locationmode= 'ISO-3', color='OBS_VALUE',labels = passenger_labels)

fig.update_layout(
    title_text = 'Total passengers flying from Schiphol Airport in 2019',
    coloraxis_colorbar_title_text = 'Total passengers',
    geo= dict(
        showframe = False,
        showcoastlines = False,
        projection_type = 'equirectangular'
    )
)
fig.show()
In [7]:
# Visualisation of passengers merged datasets in 2019
fig = px.bar(map_data_passengers_2019.sort_values('OBS_VALUE',ascending= False).head(20),\
    x= 'country_2_name', y = 'OBS_VALUE',labels=passenger_labels)

fig.update_layout(
    title_text = 'Total passengers transported by air from Schiphol Airport in 2019',
)
fig.show()

The above graphs shows how well connected Amsterdam Airport Schipol is. Passengers are being transported to the entire world. Amsterdam is directly connected to almost all of the worlds continents. The main bulk of passengers are transported to European countries. Out of the top 10 countries, only the United States of America is not part of Europe. Over 10 million passengers are transported from Amsterdam to airports in the United Kingdom.

In [8]:
# Visualisation of passengers merged datasets in 2021
map_data_passengers_2021 = world.merge(passengers_for_map_2021,left_on = 'iso_a3', right_on = 'iso_3_country', how = 'left')

fig = px.choropleth(map_data_passengers_2021, hover_name = 'country_2_name',locations= 'iso_3_country', \
    locationmode= 'ISO-3', color='OBS_VALUE',labels = passenger_labels)

fig.update_layout(
    title_text = 'Total passengers flying from Schiphol Airport in 2021',
    coloraxis_colorbar_title_text = 'Total passengers',
    geo= dict(
        showframe = False,
        showcoastlines = False,
        projection_type = 'equirectangular'
    )
)
fig.show()
In [9]:
# Visualisation of passengers merged datasets in 2021
fig = px.bar(map_data_passengers_2021.sort_values('OBS_VALUE',ascending= False).head(20),\
    x= 'country_2_name', y = 'OBS_VALUE',labels=passenger_labels)

fig.update_layout(
    title_text = 'Total passengers transported by air from Schiphol Airport in 2021',
)
fig.show()

The two above graphs show change in the amount of passengers transported from Amsterdam Airport Schiphol. The top 10 changed drastrically and the amount of passengers is hugely decreased. When looking at the connection from Amsterdam Airport Schiphol to airports in the UK, only 10% of the volume is still flying.

In [10]:
# Visualisation of cargo merged datasets in 2019
map_data_cargo_2019 = world.merge(cargo_for_map_2019,left_on = 'iso_a3', right_on = 'iso_3_country', how = 'left')

fig = px.choropleth(map_data_cargo_2019, hover_name = 'country_2_name',locations= 'iso_3_country', \
    locationmode= 'ISO-3', color='OBS_VALUE',labels = cargo_labels)

fig.update_layout(
    title_text = 'Total tons transported by air from Schiphol Airport in 2019',
    geo= dict(
        showframe = False,
        showcoastlines = False,
        projection_type = 'equirectangular'
    )
)
fig.show()
In [11]:
# Visualisation of cargo merged datasets in 2019
fig = px.bar(map_data_cargo_2019.sort_values('OBS_VALUE',ascending= False).head(20),\
    x= 'country_2_name', y = 'OBS_VALUE',labels= cargo_labels)
fig.update_layout(
    title_text = 'Total tons transported by air from Schiphol Airport in 2019',
    geo= dict(
        showframe = False,
        showcoastlines = False,
        projection_type = 'equirectangular'
    )
)
fig.show()

The amount of cargo transported from Amsterdam Airport Schiphol to the world shows a entire different distribution when compared to the passenger transport. In the top 10, no European countries can be found. In 2019, the main bulk of cargo was transported to airports in China. Followed by the United States of America.

In [12]:
# Visualisation of passengers merged datasets in 2021
map_data_cargo_2021 = world.merge(cargo_for_map_2021,left_on = 'iso_a3', right_on = 'iso_3_country', how = 'left')

fig = px.choropleth(map_data_cargo_2021, hover_name = 'country_2_name',locations= 'iso_3_country', \
    locationmode= 'ISO-3', color='OBS_VALUE',labels = cargo_labels)

fig.update_layout(
    title_text = 'Total tons transported by air from Schiphol Airport in 2021',
    geo= dict(
        showframe = False,
        showcoastlines = False,
        projection_type = 'equirectangular'
    )
)
fig.show()
In [13]:
# Visualisation of passengers merged datasets in 2021
fig = px.bar(map_data_cargo_2021.sort_values('OBS_VALUE',ascending= False).head(20),\
    x= 'country_2_name', y = 'OBS_VALUE',labels= cargo_labels)
fig.update_layout(
    title_text = 'Total tons transported by air from Schiphol Airport in 2021',
    geo= dict(
        showframe = False,
        showcoastlines = False,
        projection_type = 'equirectangular'
    )
)
fig.show()

Where as the amount of passengers drastically decreased from 2019 to 2021, the amount of cargo has stayed pretty much similiar. The countries within the top 10 changed a little, but when looking at the total cargo transport from Amsterdam Airport Schiphol to China it is similiar. The amount of cargo transported to the United States of America has even increased.

2. What is the top 5 of frequent destinations for passenger transport from Amsterdam Schiphol Airport (2019)?¶

In [14]:
# Set up definition
def top_n_year(df,n,year):
    # This function has a dataframe, a number of entries and a year as inputs and 
    # as output the dataframe filtered for the top n countries on a specific year
    topn = df.groupby(['Year',"airp_country_2"]).sum()
    topn = topn.loc[year,:].sort_values("OBS_VALUE", ascending= False).head(n).reset_index()
    cleaned = df[df["airp_country_2"].isin(topn["airp_country_2"])]
    return cleaned
In [15]:
# Call defined functions for passengers and cargo dataset
top_passengers = codes_correction(top_n_year(passengers,5,'2019'),'airp_country_2')
top_cargo = codes_correction(top_n_year(cargo,5,'2019'),'airp_country_2')
In [16]:
# Calling the top 5 countries for passenger transport

top_5_countries_passengers = top_passengers.country_2_name.unique()
for i in top_5_countries_passengers:
    print(i)
Germany
Spain
Italy
United Kingdom
United States

3. What is the top 5 of frequent destinations for cargo transport from Amsterdam Schiphol Airport (2019)?¶

In [17]:
# Calling the top 5 countries for cargo transport
top_5_countries_cargo = top_cargo.country_2_name.unique()
for i in top_5_countries_cargo:
    print(i)
United Arab Emirates
Brazil
China
Qatar
United States

4. What are the volumes of these top 5's in the last 20 years?¶

In [18]:
# Line chart for passenger data from top 5 countries
total_passengers = top_passengers.groupby(['airp_country_2','Year']).sum()
total_passengers = total_passengers.reset_index()
total_passengers = codes_correction(total_passengers,'airp_country_2')
fig = px.line(total_passengers, x='Year', y= 'OBS_VALUE' ,color='country_2_name',labels= passenger_labels, title = 'Passenger data for top 5 countries' )
fig.show()

The above graph shows the historical passenger data from the top 5 countries. The unprecedented decline that COVID-19 caused on the passenger data can be seen from 2020 onwards. Other historical events on the worlds stage like the World Trade Center bombing in 2001 or the world economic crisis in 2008 had barelly effect compared to the pandemic.

In [19]:
# Line chart for cargo data from top 5 countries
total_cargo = top_cargo.groupby(['airp_country_2','Year']).sum()
total_cargo = total_cargo.reset_index()
total_cargo = codes_correction(total_cargo,'airp_country_2')
fig = px.line(total_cargo, x='Year', y= 'OBS_VALUE' ,color='country_2_name',labels=cargo_labels, title = 'Cargo data for top 5 countries')
fig.show()

Compared to the passenger data, the cargo data contains less trends. Where as the amount of passengers dropped dramatically after the beginning of the pandemic, the cargo data increases after 2021. The decreases from 2021 to 2022 can be explained because the 2022 is not complete yet.

In this historical data the difference between the countries is also more clear. From 2000 onwards China has seen a huge growth of their flight cargo data to and from Amsterdam, where as the US has been a steady provider of cargo in Amsterdam.

5. How did the COVID-19 cases develop in these countries in the last two years?¶

In [20]:
# Select the columns of interest from the original dataset and filter it, also expand the date to accomodate year and month
columns_of_interest = ['new_cases_smoothed_per_million','people_fully_vaccinated_per_hundred','date','location']
filtered_covid_data = covid_data[columns_of_interest]
filtered_covid_data[['Year','Month','Day']] = filtered_covid_data.date.str.split("-",expand=True)

# Selecting the countries of interest for cargo and passenger transport
cargo_countries_of_interest =['China','United States','United Arab Emirates','Brazil','Qatar','Netherlands']
passenger_countries_of_interest = ['United Kingdom','Spain','Germany','Italy','United States','Netherlands']

# Group by year, month and location to calculate the mean for cargo transport
cargo_filtered_covid_data = filtered_covid_data[filtered_covid_data['location'].isin(cargo_countries_of_interest)]
cargo_filtered_covid_data = cargo_filtered_covid_data.groupby(['location','Year','Month']).mean()

# Resetting the index and creating new collum with Year and Month 
cargo_filtered_covid_data = cargo_filtered_covid_data.reset_index()
cargo_filtered_covid_data['date'] = cargo_filtered_covid_data['Year'] + ['-'] + cargo_filtered_covid_data['Month'] 

# Group by year, month and location to calculate the mean for cargo transport
passenger_filtered_covid_data = filtered_covid_data[filtered_covid_data['location'].isin(passenger_countries_of_interest)]
passenger_filtered_covid_data = passenger_filtered_covid_data.groupby(['location','Year','Month']).mean()

#Resetting the index and creating new collum with Year and Month 
passenger_filtered_covid_data = passenger_filtered_covid_data.reset_index()
passenger_filtered_covid_data['date'] = passenger_filtered_covid_data['Year'] + ['-'] + passenger_filtered_covid_data['Month']
In [21]:
# Calling visualization top 5 countries for passenger transport

fig = px.line(passenger_filtered_covid_data, x='date', y= 'new_cases_smoothed_per_million' ,color='location',
                title= 'New covid cases in the top 5 countries for passenger transport', labels={
                     'new_cases_smoothed_per_million': 'Covid cases per million',
                     'date' : 'Date',
                     'location' : 'Country'})

fig.show()
In [22]:
# Calling visualization top 5 countries for cargo transport

fig = px.line(cargo_filtered_covid_data, x='date', y= 'new_cases_smoothed_per_million', color='location',
              title= 'New covid cases in the top 5 countries for cargo transport', labels={
                     'new_cases_smoothed_per_million': 'Covid cases per million',
                     'date' : 'Date',
                     'location' : 'Country'}, range_y=[0,4000] )

fig.show()

6. How did the vaccination rate for COVID 19 develop in these countries in the last two years?¶

In [23]:
# Calling visualization top 5 countries for passenger transport

fig = px.line(passenger_filtered_covid_data, x='date', y= 'people_fully_vaccinated_per_hundred' ,color='location',
               title= 'Vaccination rate in percent in the top 5 countries for passenger transport', labels={
                     'people_fully_vaccinated_per_hundred' : 'People fully vaccinated (%)',
                     'date' : 'Date',
                     'location' : 'Country'})

fig.show()
In [24]:
# Calling visualization top 5 countries for cargo transport

fig = px.line(cargo_filtered_covid_data, x='date', y= 'people_fully_vaccinated_per_hundred' ,color='location',
                title= 'Vaccination rate in percent in the top 5 countries for cargo transport', labels={
                     'people_fully_vaccinated_per_hundred' : 'People fully vaccinated (%)',
                     'date' : 'Date',
                     'location' : 'Country'})

fig.show()

7. What impact did the COVID-19 cases have on the passenger transport from Amsterdam Schiphol Airport ?¶

In [25]:
#Data correction passengers
passengers_pre_merge = top_passengers.groupby(['airp_country_2','TIME_PERIOD','Month']).sum()
passengers_pre_merge = passengers_pre_merge.reset_index()
passengers_pre_merge = passengers_pre_merge[passengers_pre_merge['TIME_PERIOD'].between('2020-01', '2022-07')]
passengers_pre_merge = codes_correction(passengers_pre_merge,'airp_country_2')

#Data correction cargo
cargo_pre_merge = top_cargo.groupby(['airp_country_2','TIME_PERIOD','Month']).sum()
cargo_pre_merge = cargo_pre_merge.reset_index()
cargo_pre_merge = cargo_pre_merge[cargo_pre_merge['TIME_PERIOD'].between('2020-01', '2022-07')]
cargo_pre_merge = codes_correction(cargo_pre_merge,'airp_country_2')

#Data correction covid
passenger_filtered_covid_data = passenger_filtered_covid_data.reset_index()
cargo_filtered_covid_data = cargo_filtered_covid_data.reset_index()


merged_passengers = pd.merge(passenger_filtered_covid_data,passengers_pre_merge, left_on=('location','date'),
right_on=('country_2_name','TIME_PERIOD'))
merged_cargo = pd.merge(cargo_filtered_covid_data,cargo_pre_merge, left_on=('location','date'),
right_on=('country_2_name','TIME_PERIOD'))
In [26]:
# Passengers and Covid
fig = make_subplots(specs=[[{"secondary_y": True}]])
# Adding all traces
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'Germany']['date'],
    y = merged_passengers[merged_passengers['location']== 'Germany']['OBS_VALUE'], name='Germany flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'Germany']['date'],
    y = merged_passengers[merged_passengers['location']== 'Germany']['new_cases_smoothed_per_million'],
     name='Germany covid'),
    secondary_y=True,
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'Italy']['date'],
    y = merged_passengers[merged_passengers['location']== 'Italy']['OBS_VALUE'], name='Italy flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'Italy']['date'],
    y = merged_passengers[merged_passengers['location']== 'Italy']['new_cases_smoothed_per_million'],
     name='Italy covid'),
    secondary_y=True,
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'United States']['date'],
    y = merged_passengers[merged_passengers['location']== 'United States']['OBS_VALUE'],
     name='United States flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'United States']['date'],
    y = merged_passengers[merged_passengers['location']== 'United States']['new_cases_smoothed_per_million'],
     name='United States covid'),
    secondary_y=True,
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'United Kingdom']['date'],
    y = merged_passengers[merged_passengers['location']== 'United Kingdom']['OBS_VALUE'],
     name='United Kingdom flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'United Kingdom']['date'],
    y = merged_passengers[merged_passengers['location']== 'United Kingdom']['new_cases_smoothed_per_million'],
     name='United Kingdom covid'),
    secondary_y=True,
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'Spain']['date'],
    y = merged_passengers[merged_passengers['location']== 'Spain']['OBS_VALUE'], name='Spain flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'Spain']['date'],
    y = merged_passengers[merged_passengers['location']== 'Spain']['new_cases_smoothed_per_million'],
     name='Spain covid'),
    secondary_y=True,
)
# Adding the dropdown menu
options = ['All','Germany','Italy','United States','United Kingdom','Spain','Covid only','Flight only']
visList = [
    [True,True,True,True,True,True,True,True,True,True],
    [True,True,False,False,False,False,False,False,False,False],
    [False,False,True,True,False,False,False,False,False,False],
    [False,False,False,False,True,True,False,False,False,False],
    [False,False,False,False,False,False,True,True,False,False],
    [False,False,False,False,False,False,False,False,True,True],
    [False,True,False,True,False,True,False,True,False,True],
    [True,False,True,False,True,False,True,False,True,False]]
buttons = []
for i, g in enumerate(options):
    button = dict(label =  g,
    method = 'restyle',
    args = ['visible',visList[i]])
    buttons.append(button)

fig.update_layout(
    xaxis_title='Date',
    yaxis_title='Number of passengers',
    title_text='Flight passengers compared to the covid cases per million',
    updatemenus=[
        dict(
            type='dropdown',
            direction='right',
            buttons = buttons,
            x = 0.13,
            y = 1.16,
            bordercolor = 'grey'   
        )
    ],
)
fig.update_yaxes(title_text='Covid cases per million people', secondary_y=True)
fig.show()

In the above graph the combination of COVID-19 new cases and the total amount of passengers transported from Amsterdam Airport Schiphol to the specific countries can be seen. Different combinations can be selected. In general when the amount of new COVID-19 cases are raising, the amount of passengers transported from Amsterdam Airport Schiphol to the country is decreased. For example, when looking at January 2022 in Italy, there's a peak in the amount of new COVID-19 cases and a valley in the amount of passengers transported. In general, it can be observed that:

  • First, the appearance of covid in 2020, although the number of cases was much lower compared to the summer of 2022, created a drastic drop in the number of flight passengers for each country. This drop is much bigger and clearer than the drop in the summer of 2022.
  • From the beginning of 2021, a real increase in the number of flight passengers can be observed. However, the increase in the number of covid cases observed from autumn 2021 onwards will cause the number of flight passengers to fall again.
  • Finally, the new increase in covid cases in the summer of 2022 again had an influence. It is already noticeable that the number of flight passengers has fallen in recent months.

8. What impact did the COVID-19 cases have on the cargo transport from Amsterdam Schiphol Airport ?¶

In [27]:
# Cargo and Covid
fig = make_subplots(specs=[[{'secondary_y': True}]])
# Adding all traces
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'China']['date'],
    y = merged_cargo[merged_cargo['location']== 'China']['OBS_VALUE'], name='China flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'China']['date'],
    y = merged_cargo[merged_cargo['location']== 'China']['new_cases_smoothed_per_million'],
     name='China covid'),
    secondary_y=True,
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'United Arab Emirates']['date'],
    y = merged_cargo[merged_cargo['location']== 'United Arab Emirates']['OBS_VALUE'],
     name='United Arab Emirates flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'United Arab Emirates']['date'],
    y = merged_cargo[merged_cargo['location']== 'United Arab Emirates']['new_cases_smoothed_per_million'],
     name='United Arab Emirates covid'),
    secondary_y=True,
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'United States']['date'],
    y = merged_cargo[merged_cargo['location']== 'United States']['OBS_VALUE'], name='United States flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'United States']['date'],
    y = merged_cargo[merged_cargo['location']== 'United States']['new_cases_smoothed_per_million'],
     name='United States covid'),
    secondary_y=True,
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'Brazil']['date'],
    y = merged_cargo[merged_cargo['location']== 'Brazil']['OBS_VALUE'], name='Brazil flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'Brazil']['date'],
    y = merged_cargo[merged_cargo['location']== 'Brazil']['new_cases_smoothed_per_million'],
     name= 'Brazil covid'),
    secondary_y=True,
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'Qatar']['date'],
    y = merged_cargo[merged_cargo['location']== 'Qatar']['OBS_VALUE'], name='Qatar flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'Qatar']['date'],
    y = merged_cargo[merged_cargo['location']== 'Qatar']['new_cases_smoothed_per_million'],
     name='Qatar covid'),
    secondary_y=True,
)

# Adding the dropdown menu
options = ['All','China','United Arab Emirates','United States','Brazil','Qatar','Covid only','Flight only']
visList = [
    [True,True,True,True,True,True,True,True,True,True],
    [True,True,False,False,False,False,False,False,False,False],
    [False,False,True,True,False,False,False,False,False,False],
    [False,False,False,False,True,True,False,False,False,False],
    [False,False,False,False,False,False,True,True,False,False],
    [False,False,False,False,False,False,False,False,True,True],
    [False,True,False,True,False,True,False,True,False,True],
    [True,False,True,False,True,False,True,False,True,False]]
buttons = []
for i, g in enumerate(options):
    button = dict(label =  g,
    method = 'restyle',
    args = ['visible',visList[i]])
    buttons.append(button)

fig.update_layout(
    xaxis_title='Date',
    yaxis_title='Transported cargo [Tonnes]',
    title_text='Flight cargo compared to the covid cases per million',
    updatemenus=[
        dict(
            type='dropdown',
            direction='right',
            buttons = buttons,
            x = 0.17,
            y = 1.16,
            bordercolor = 'grey'   
        )
    ],
)
fig.update_yaxes(title_text='Covid cases per million people', secondary_y=True)
fig.show()

In the above graph the combination of COVID-19 new cases and the total amount of cargo transported from Amsterdam Airport Schiphol to the specific countries can be seen. Different combinations can be selected. One trend is less obvious than for the previous point. However, in general, when the amount of new COVID-19 cases are raising, the amount of cargo transported from Amsterdam Airport Schiphol to the country is decreased. As a result, the peaks of the epidemic can be observed on the cargo transport graph.

9. What impact did the vaccination rate have on the passenger transport from Amsterdam Schiphol Airport ?¶

In [28]:
# Passengers and vaccination
fig = make_subplots(specs=[[{'secondary_y': True}]])
# Adding all traces
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'Germany']['date'],
    y = merged_passengers[merged_passengers['location']== 'Germany']['OBS_VALUE'], name='Germany flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'Germany']['date'],
    y = merged_passengers[merged_passengers['location']== 'Germany']['people_fully_vaccinated_per_hundred'], 
    name='Germany vaccinations'),
    secondary_y=True,
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'Italy']['date'],
    y = merged_passengers[merged_passengers['location']== 'Italy']['OBS_VALUE'], name='Italy flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'Italy']['date'],
    y = merged_passengers[merged_passengers['location']== 'Italy']['people_fully_vaccinated_per_hundred'],
     name='Italy vaccinations'),
    secondary_y=True,
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'United States']['date'],
    y = merged_passengers[merged_passengers['location']== 'United States']['OBS_VALUE'],
     name='United States flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'United States']['date'],
    y = merged_passengers[merged_passengers['location']== 'United States']['people_fully_vaccinated_per_hundred'], 
    name='United States vaccinations'),
    secondary_y=True,
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'United Kingdom']['date'],
    y = merged_passengers[merged_passengers['location']== 'United Kingdom']['OBS_VALUE'],
     name='United Kingdom flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'United Kingdom']['date'],
    y = merged_passengers[merged_passengers['location']== 'United Kingdom']['people_fully_vaccinated_per_hundred'],
     name='United Kingdom vaccinations'),
    secondary_y=True,
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'Spain']['date'],
    y = merged_passengers[merged_passengers['location']== 'Spain']['OBS_VALUE'], name='Spain flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_passengers[merged_passengers['location']== 'Spain']['date'],
    y = merged_passengers[merged_passengers['location']== 'Spain']['people_fully_vaccinated_per_hundred'],
     name='Spain vaccinations'),
    secondary_y=True,
)

# Adding the dropdown menu
options = ['All','Germany','Italy','United States','United Kingdom',
            'Spain','Vaccinations only','Flight only']
visList = [
    [True,True,True,True,True,True,True,True,True,True],
    [True,True,False,False,False,False,False,False,False,False],
    [False,False,True,True,False,False,False,False,False,False],
    [False,False,False,False,True,True,False,False,False,False],
    [False,False,False,False,False,False,True,True,False,False],
    [False,False,False,False,False,False,False,False,True,True],
    [False,True,False,True,False,True,False,True,False,True],
    [True,False,True,False,True,False,True,False,True,False]]
buttons = []
for i, g in enumerate(options):
    button = dict(label =  g,
    method = 'restyle',
    args = ['visible',visList[i]])
    buttons.append(button)

fig.update_layout(
    xaxis_title='Date',
    yaxis_title='Number of passengers',
    title_text='Flight passengers compared to the percentage of vaccinated people',
    updatemenus=[
        dict(
            type='dropdown',
            direction='right',
            buttons = buttons,
            x = 0.13,
            y = 1.16,
            bordercolor = 'grey'   
        )
    ],
)
fig.update_yaxes(title_text='Fully vaccinated people [%]' , secondary_y=True)
fig.show()

In the above graph the combination of the percentage of fully vaccinated people and the total amount of passengers transported from Amsterdam Airport Schiphol to the specific countries can be seen. Different combinations can be selected. For all countries, the first part of the vaccination campaign was successful. Indeed, the number of covid cases has been more or less controlled. However, the appearance of new variants has reduced the effectiveness of the vaccines. Increases in the number of cases were again observed. As a result, the number of flight passengers and the rate of vaccination are linked from January 2021 to August 2021, when the effects of vaccination were most noticed. Thereafter, as the number of Covid cases increases again, the umber of flight passengers decreases (and increases again) while vaccination continues to increase.

10. What impact did the vaccination rate have on the cargo transport from Amsterdam Schiphol Airport ?¶

In [29]:
# Cargo and vaccination 
fig = make_subplots(specs=[[{'secondary_y': True}]])
# Adding all traces
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'China']['date'],
    y = merged_cargo[merged_cargo['location']== 'China']['OBS_VALUE'], name='China flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'China']['date'],
    y = merged_cargo[merged_cargo['location']== 'China']['people_fully_vaccinated_per_hundred'],
     name='China vaccinations'),
    secondary_y=True,
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'United Arab Emirates']['date'],
    y = merged_cargo[merged_cargo['location']== 'United Arab Emirates']['OBS_VALUE'], 
    name='United Arab Emirates flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'United Arab Emirates']['date'],
    y = merged_cargo[merged_cargo['location']== 'United Arab Emirates']['people_fully_vaccinated_per_hundred'],
     name='United Arab Emirates vaccinations'),
    secondary_y=True,
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'United States']['date'],
    y = merged_cargo[merged_cargo['location']== 'United States']['OBS_VALUE'], name='United States flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'United States']['date'],
    y = merged_cargo[merged_cargo['location']== 'United States']['people_fully_vaccinated_per_hundred'],
     name='United States vaccinations'),
    secondary_y=True,
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'Brazil']['date'],
    y = merged_cargo[merged_cargo['location']== 'Brazil']['OBS_VALUE'], name='Brazil flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'Brazil']['date'],
    y = merged_cargo[merged_cargo['location']== 'Brazil']['people_fully_vaccinated_per_hundred'],
     name= 'Brazil vaccinations'),
    secondary_y=True,
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'Qatar']['date'],
    y = merged_cargo[merged_cargo['location']== 'Qatar']['OBS_VALUE'], name='Qatar flight'),
    secondary_y=False
)
fig.add_trace(
    go.Scatter(x = merged_cargo[merged_cargo['location']== 'Qatar']['date'],
    y = merged_cargo[merged_cargo['location']== 'Qatar']['people_fully_vaccinated_per_hundred'],
     name='Qatar vaccinations'),
    secondary_y=True,
)

# Adding the dropdown menu
options = ['All','China','United Arab Emirates','United States','Brazil',
            'Qatar','Vaccinations only','Flight only']
visList = [
    [True,True,True,True,True,True,True,True,True,True],
    [True,True,False,False,False,False,False,False,False,False],
    [False,False,True,True,False,False,False,False,False,False],
    [False,False,False,False,True,True,False,False,False,False],
    [False,False,False,False,False,False,True,True,False,False],
    [False,False,False,False,False,False,False,False,True,True],
    [False,True,False,True,False,True,False,True,False,True],
    [True,False,True,False,True,False,True,False,True,False]]
buttons = []
for i, g in enumerate(options):
    button = dict(label =  g,
    method = 'restyle',
    args = ['visible',visList[i]])
    buttons.append(button)

fig.update_layout(
    xaxis_title='Date',
    yaxis_title='Transported cargo [Tonnes]',
    title_text='Flight cargo compared to the percentage of people vaccinated',
    updatemenus=[
        dict(
            type='dropdown',
            direction='right',
            buttons = buttons,
            x = 0.15,
            y = 1.16,
            bordercolor = 'grey'   
        )
    ],
)
fig.update_yaxes(title_text='Fully vaccinated people [%]', secondary_y=True)
fig.show()

In the above graph the combination of the percentage of fully vaccinated people and the total amount of cargo transported from Amsterdam Airport Schiphol to the specific countries can be seen. Different combinations can be selected. The effect of fully vaccinated people in the country compared to the amount of cargo transport from Amsterdam Airport Schiphol to that country is not as visible, compared to the amount of passengers transported to that country.

11. What is the impact of COVID 19 on the other Dutch airports?¶

In [30]:
#Import of the data
filepath = 'Data_Sets/Dutch Airports.csv'
DutchAirports = pd.read_csv(filepath, delimiter=';')

#Construction of the wanted data frame by manipulating the original data frame
DutchAirports = DutchAirports.drop(['Aircraft movements/Cross-country flights (number)',
                                     'Aircraft movements/Local flights (number)', 
                                     'Commercial air traffic/Flights/All flights/Scheduled (number)'],
                                      axis = 1)
DutchAirports = DutchAirports.set_index('Airports')
DutchAirports = DutchAirports.T
DutchAirports = DutchAirports.drop(['Total Dutch airports'], axis = 1)
DutchAirports = DutchAirports.T
DutchAirports = DutchAirports.reset_index()
DutchAirports = DutchAirports.set_index('Periods')
DutchAirports = DutchAirports.T
DutchAirports = DutchAirports.drop(['2018'], axis = 1)
DutchAirports = DutchAirports.drop(['2019'], axis = 1)
DutchAirports = DutchAirports.drop(['2020*'], axis = 1)
DutchAirports = DutchAirports.drop(['2021*'], axis = 1)
DutchAirports = DutchAirports.T
DutchAirports = DutchAirports.reset_index()
#Creating 4 new columns with the purcentage of change from one year to the next one
DutchAirports['PC_flights'] = DutchAirports['Commercial air traffic/Flights/All flights/Total flights (number)'].pct_change()*100
DutchAirports['PC_pass'] = DutchAirports['Commercial air traffic/Passengers/Total passengers/Total passengers (number)'].pct_change()*100
DutchAirports['PC_cargo'] = DutchAirports['Commercial air traffic/Cargo/Total cargo/Total cargo (ton)'].pct_change()*100
DutchAirports['PC_mail'] = DutchAirports['Commercial air traffic/Mail/Total mail/Total mail (ton)'].pct_change()*100
#Remplace all the NA value with zeros
DutchAirports = DutchAirports.fillna(0)

First, in the first step the differences in the number of air traffic flights is shown. As the quantities are not at all the same (much more flights in Schipol than in the other airports), it seems more relevant to compare the percentages of change from one month to another in each airport. The second figure shows the same data but in a more dynamic way.

In [31]:
#Interactive plot (color makes possible to select on right of graph)
fig = px.line(DutchAirports, x='Periods', y= 'PC_flights', color='Airports',
                 title= 'Percentage of variation in the number of commercial air traffic flights',
                 labels={
                   #Change label names
                   'PC_flights': 'Variation [%]',
                   'Periods': 'Date'
               }, )

#Add range selector to zoom in on periods in Y axis.
fig.update_layout(
    xaxis=dict(
        rangeselector=dict(
            buttons=list([
                dict(count=1,
                     step='month',
                     stepmode='backward'),
            ])
        ),
        rangeslider=dict(
            visible=True
        ),
    )
)

#Show the graph
fig.show()

We can also visualize it in a more dynamic plot:

In [32]:
#Dynamic plot
fig = px.bar(DutchAirports, x='PC_flights', y= 'Airports', color='Airports', animation_frame='Periods', 
                 animation_group='Airports', orientation='h',
                  title= 'Percentage of variation in the number of commercial air traffic flights',
                 labels={
                   #Change label names
                   'PC_flights': 'Variation [%]',
                   'Periods': 'Date',
               }, ) 

fig.update_layout(showlegend=False,xaxis_range = [-100,800])
                 
#Show the graph
fig.show()

Then, the differences in the number of commercial air traffic passengers is visualized, for commercial air traffic cargo and the commercial air traffic mail.

In [33]:
#Interactive plot (color makes possible to select on right of graph)
fig = px.line(DutchAirports, x='Periods', y= 'Commercial air traffic/Passengers/Total passengers/Total passengers (number)' ,color='Airports', title= 'Commercial air traffic passengers',
                 labels={
                   #Change label names
                   'Commercial air traffic/Passengers/Total passengers/Total passengers (number)': 'Commercial air traffic passengers',
                   'Periods': 'Date',
               }, )

#Add range selector to zoom in on periods in Y axis.
fig.update_layout(
    xaxis=dict(
        rangeselector=dict(
            buttons=list([
                dict(count=1,
                     step='month',
                     stepmode='backward'),
            ])
        ),
        rangeslider=dict(
            visible=True
        ),
    )
)
                 

#Show the graph
fig.show()
In [34]:
#Interactive plot (color makes possible to select on right of graph)
fig = px.line(DutchAirports, x='Periods', y= 'Commercial air traffic/Cargo/Total cargo/Total cargo (ton)' ,color='Airports', title= 'Commercial air traffic cargo [ton]',
                 labels={
                   #Change label names
                   'Commercial air traffic/Cargo/Total cargo/Total cargo (ton)': 'Commercial air traffic cargo [ton]',
                   'Periods': 'Date',
               }, 
                 )

#Add range selector to zoom in on periods in Y axis.
fig.update_layout(
    xaxis=dict(
        rangeselector=dict(
            buttons=list([
                dict(count=1,
                     step='month',
                     stepmode='backward'),
            ])
        ),
        rangeslider=dict(
            visible=True
        ),
    )
)

#Show the graph
fig.show()
In [35]:
#Interactive plot (color makes possible to select on right of graph: practical to zoom on the smaller airports)
fig = px.line(DutchAirports, x='Periods', y= 'Commercial air traffic/Mail/Total mail/Total mail (ton)' ,color='Airports', title= 'Commercial air traffic mail [ton]',
                 labels={
                   #Change label names
                   'Commercial air traffic/Mail/Total mail/Total mail (ton)': 'Commercial air traffic mail [ton]',
                   'Periods': 'Date',
               }, 
                 )

#Add range selector to zoom in on periods in Y axis.
fig.update_layout(
    xaxis=dict(
        rangeselector=dict(
            buttons=list([
                dict(count=1,
                     step='month',
                     stepmode='backward'),
            ])
        ),
        rangeslider=dict(
            visible=True
        ),
    )
)

#Show the graph
fig.show()

This graph shows that Schipol is the only airport in the Netherlands where mails transit. This graph is therefore less interesting for answering the sub-question. However, it does provide some interesting information.

From all these visualisations we can conclude that, in general, all airports in the Netherlands have suffered the same consequences from Covid. By going into more detail in each of the visualisations:

  • Regarding the number of commercial air flights, increases can be observed during the summer periods due to the recovery of air traffic and the abandonment of the strict restrictive measures. It can be seen that the curves have generally the same shape and therefore the same trends.
  • For commercial air flight passengers, the curves also have the same shapes. They follow the different waves of the epidemic and the different restrictive measures used to control the covid 19 epidemic. It is interesting to remove the airports with the largest numbers from the graph (by selecting them in the legend on the right hand side) each time in order to zoom in on the smaller airports. By doing this, it is clear that all the curves have the same appearance: a drop at the beginning of 2020, an increase in summer 2020, a drop between 2020 and 2021, an increase in summer 2021, a drop at the end of 2021 and then an increase until today.
  • Finally, for the commercial air traffic cargo, only Schipol and Maastricht Airport have data. However, again, their curves have the same shape which again indicates that covid has had the same effects but on a different scale as the two airports are not at all the same size and therefore do not carry the same quantities of goods

Conclusion¶

The impact of COVID-19 on the aviation from Amsterdam Airport Schiphol is huge. The different sub-research questions show that a certain decrease of flight (both passengers and cargo) has not been seen before in the history of flight. Not only for Amsterdam Airport Schiphol but also for the other airports in the Netherlands the same conclusions can be drawn.

The good news however, when we look at the way the pandemic has been handled a recovery can be seen. When combining the vaccination rate and the amount of flight to the specific countries a recovery can be seen. But whether or not the recovery is going to be as big as the way people and cargo have been flown before, that is still unknown.

Extra: COVID-data in China¶

While discussing the first research question we noticed that, even though is has been proven that COVID-19 arised in China, the amount of COVID cases are very low. We decided to investige this futher. For the first part of the visualisation, we decided to compare the impact on the transport sector of the start of Covid in the Netherlands and in China. In this way, it will be possible to compare the two situations in order to understand whether the Chinese have really been able to escape Covid and its impacts or not. Indeed, as their number of cases is officially so low, it would be possible to think that their economy has not been impacted. But is this really the case? What were the influences of the covid on the country compared to the Netherlands? We decided to proceed as follows:

  • First, we will compare the purely covid-related data between the two countries.
  • Then, we will analyse the behaviour of the transport economy in China in order to compare it to that of the Netherlands.

Quantities cannot be compared as such. After all, China is one of the world's largest powers, which is in no way comparable with the Netherlands. However, it is possible to compare the trend of the different curves when the first wave of Covid appeared (increasing, decreasing, stagnating).

In [36]:
# Import 
filepath = 'Data_Sets/owid-covid-data.csv'
covid_data = pd.read_csv(filepath, delimiter=',')

# Select the columns of interest from the original dataset and filter it, also expand the date to accomodate year and month
columns_of_interest = ['new_cases_smoothed_per_million','people_fully_vaccinated_per_hundred','date','location']
filtered_covid_data = covid_data[columns_of_interest]
filtered_covid_data[['Year','Month','Day']] = filtered_covid_data.date.str.split("-",expand=True)
filtered_covid_data.head()

#Select the countrys of interest 
Covid_China = filtered_covid_data[filtered_covid_data['location'].isin(['Netherlands','China'])]
In [37]:
# Import the different datasets 

filepath1 = 'Data_Sets/Passengers.csv'
Passengers = pd.read_csv(filepath1, delimiter=',')

# Unuseful columns are removed
Passengers_drop = Passengers.drop(['Country Code', 'Indicator Name', 'Indicator Code'],  axis=1)
Passengers_drop.set_index('Country', inplace=True) 
Passengers_wanted = Passengers_drop.T

# Selection of the wanted data
China_passengers_final = Passengers_wanted.China.reset_index()
China_passengers_final.columns = ['Year', 'Number of passengers carried, China']
NL_passengers_final = Passengers_wanted.Netherlands.reset_index()
NL_passengers_final.columns = ['Year', 'Number of passengers carried, NL']

# Import of the data
filepath2 = 'Data_Sets/Freight.csv'
Freight = pd.read_csv(filepath2, delimiter=',')

# Unuseful columns are removed
Freight_drop = Freight.drop(['Country Code', 'Indicator Name', 'Indicator Code'],  axis=1)
Freight_drop.set_index('Country Name', inplace=True) 
Freight_wanted = Freight_drop.T

# Selection of the wanted data
NL_freight_final = Freight_wanted.Netherlands.reset_index()
NL_freight_final.columns = ['Year', 'Volume of freight carried, NL']
China_freight_final = Freight_wanted.China.reset_index()
China_freight_final.columns = ['Year', 'Volume of freight carried, China']

# Import of the data
filepath3 = 'Data_Sets/Container.csv'
Container = pd.read_csv(filepath3, delimiter=',')

# Unuseful columns are removed
Container_drop = Container.drop(['Country Code', 'Indicator Name', 'Indicator Code'],  axis=1)
Container_drop.set_index('Country Name', inplace=True) 
Container_wanted = Container_drop.T

# Selection of the wanted data
China_container_final = Container_wanted.China.reset_index()
China_container_final.columns = ['Year', 'Flow of containers carried, China']
NL_container_final = Container_wanted.Netherlands.reset_index()
NL_container_final.columns = ['Year', 'Flow of containers carried, NL']

# Import of the data
filepath4 = 'Data_Sets/CO2_emissions.csv'
CO2 = pd.read_csv(filepath4, delimiter=',')

# Unuseful columns are removed
CO2_drop = CO2.drop(['Country Code', 'Indicator Name', 'Indicator Code'],  axis=1)
CO2_drop.set_index('Country Name', inplace=True) 
CO2_wanted = CO2_drop.T

# Selection of the wanted data
NL_CO2_final = CO2_wanted.Netherlands.reset_index()
NL_CO2_final.columns = ['Year', 'Carbon dioxide emissions, NL']
China_CO2_final = CO2_wanted.China.reset_index()
China_CO2_final.columns = ['Year', 'Carbon dioxide emissions, China']

# Import of the data
filepath5 = 'Data_Sets/Lifeexp.csv'
Lifeexp = pd.read_csv(filepath5, delimiter=',')

# Unuseful columns are removed
Lifeexp_drop = Lifeexp.drop(['Country Code', 'Indicator Name', 'Indicator Code'],  axis=1)
Lifeexp_drop.set_index('Country Name', inplace=True) 
Lifeexp_wanted = Lifeexp_drop.T

# Selection of the wanted data
NL_Lifeexp_final = Lifeexp_wanted.Netherlands.reset_index()
NL_Lifeexp_final.columns = ['Year', 'Life expectancy, NL']
China_Lifeexp_final = Lifeexp_wanted.China.reset_index()
China_Lifeexp_final.columns = ['Year', 'Life expectancy, China']

# Import of the data
filepath6 = 'Data_Sets/GDP.csv'
GPD = pd.read_csv(filepath6, delimiter=',')

# Unuseful columns are removed
GPD_drop = GPD.drop(['Country Code', 'Indicator Name', 'Indicator Code'],  axis=1)
GPD_drop.set_index('Country Name', inplace=True) 
GPD_wanted = GPD_drop.T

# Selection of the wanted data
NL_GPD_final = GPD_wanted.Netherlands.reset_index()
NL_GPD_final.columns = ['Year', 'GDP growth, NL']
China_GPD_final = GPD_wanted.China.reset_index()
China_GPD_final.columns = ['Year', 'GDP growth, China']
In [38]:
#Merging the data on the column 'Year'
df1 = pd.merge(NL_passengers_final, China_passengers_final, how='outer', on='Year')
df1 = pd.merge(df1, NL_freight_final, how='outer', on='Year')
df1 = pd.merge(df1, China_freight_final, how='outer', on='Year')
df1 = pd.merge(df1, NL_container_final, how='outer', on='Year')
df1 = pd.merge(df1, China_container_final, how='outer', on='Year')
df1 = pd.merge(df1, NL_CO2_final, how='outer', on='Year')
df1 = pd.merge(df1, China_CO2_final, how='outer', on='Year')
df2 = pd.merge(China_Lifeexp_final, NL_Lifeexp_final, how='outer', on='Year')
df2 = pd.merge(df2, NL_GPD_final, how='outer', on='Year')
df2 = pd.merge(df2, China_GPD_final, how='outer', on='Year')
df1 = df1.iloc[ 0:61, : ]
df2 = df2.iloc[ 0:61, : ]
In [39]:
#Interactive plot (color makes possible to select on right of graph)
fig = px.line(Covid_China, x='date', y= 'new_cases_smoothed_per_million' ,color='location',
title= 'New covid cases smoothed per million in the Netherlands and in China',
 labels={
                   #Change label names
                   'new_cases_smoothed_per_million': 'New covid cases smoothed per million',
                   'date': 'Date'
               }, ) 

# Add annotations of important moments
fig.add_annotation(x='2020-11-03', y=490, ax='2020-10-29', ay=3000, text='Increase Lockdown',
                    xref='x', yref='y', axref='x', ayref='y')

fig.add_annotation(x='2020-12-14', y=513, ax='2021-01-01', ay=2000, text='Full Lockdown',
                    xref='x', yref='y', axref='x', ayref='y')

fig.add_annotation(x='2021-12-20', y=746, ax='2021-11-25', ay=2500, text='Full Lockdown',
                    xref='x', yref='y', axref='x', ayref='y')

#Show the graph
fig.show()

As the graph above shows, China has indeed recorded very few cases. The Netherlands, on the other hand, has a curve that is dictated by the different epidemic waves. China's curve even seems to be constantly zero. However, they did consider some cases as shown below:

In [40]:
#Interactive plot (color makes possible to select on right of graph)
fig = px.line(Covid_China, x='date', y= 'new_cases_smoothed_per_million' ,color='location',
                range_x= ['2020-01-22', '2020-03-31'], range_y=[0,60],
                 title= 'New covid cases smoothed per million in the Netherlands and in China between January and March 2020',
                 labels={
                   #Change label names
                   'new_cases_smoothed_per_million': 'New covid cases smoothed per million',
                   'date': 'Date'
               }, ) 

#Show the graph
fig.show()

This period is the very beginning of the pandemic. The Netherlands had not even started to register cases. However, the number of cases remains relatively low compared to the large population of China.

In [41]:
#Interactive plot (color makes possible to select on right of graph)
fig = px.line(Covid_China, x='date', y= 'new_cases_smoothed_per_million' ,color='location',
                range_x= ['2022-04-01', '2022-05-31'], range_y=[0,200],
                title = 'New covid cases smoothed per million in the Netherlands and in China between April and May 2022',
                labels={
                   #Change label names
                   'new_cases_smoothed_per_million': 'New covid cases smoothed per million',
                   'date': 'Date'
               }, ) 

#Show the graph
fig.show()

As can be seen above, a tiny peak in covid can also be seen in April 2022.

In [42]:
#Interactive plot (color makes possible to select on right of graph)
fig = px.line(df1, x='Year', y= ['Number of passengers carried, NL', 'Number of passengers carried, China'],
                 title = 'Number of passengers carried',
                labels={
                   #Change label name
                   'value': 'Number of passengers carried'

               }, ) 

#Show the graph
fig.show()
In [43]:
#Interactive plot (color makes possible to select on right of graph)
fig = px.line(df1, x='Year', y= ['Volume of freight carried, NL', 'Volume of freight carried, China'],
                 title = 'Volume of freight carried (in metric tons times kilometers traveled)',
                labels={
                   #Change label name
                   'value': 'Volume of freight carried'

               }, ) 

#Show the graph
fig.show()
In [44]:
#Interactive plot (color makes possible to select on right of graph)
fig = px.line(df1, x='Year', y= ['Flow of containers carried, NL', 'Flow of containers carried, China'],
                 title = 'Flow of containers carried (in twenty-foot equivalent units (TEUs))',
                labels={
                   #Change label name
                   'value': 'Flow of containers carried'

               }, ) 

#Show the graph
fig.show()
In [45]:
#Interactive plot (color makes possible to select on right of graph)
fig = px.line(df1, x='Year', y= ['Carbon dioxide emissions, NL', 'Carbon dioxide emissions, China'],
                 title = 'Carbon dioxide emissions',
                labels={
                   #Change label name
                   'value': 'Carbon dioxide emissions'

               }, ) 

#Show the graph
fig.show()
In [46]:
#Interactive plot (color makes possible to select on right of graph)
fig = px.line(df2, x='Year', y= ['Life expectancy, NL', 'Life expectancy, China'],
                 title = 'Life expectancy',
                labels={
                   #Change label name
                   'value': 'Life expectancy'

               }, ) 

#Show the graph
fig.show()
In [47]:
#Interactive plot (color makes possible to select on right of graph)
fig = px.line(df2, x='Year', y= ['GDP growth, NL', 'GDP growth, China'],  title = 'GDP growth',
                labels={
                   #Change label name
                   'value': 'GDP growth'

               }, ) 

#Show the graph
fig.show()

All these graphs allow us to make several observations:

  • With regard to the number of passengers carried, both countries observe a decline when the COVID-19 pandemic begins in 2019. It is remarkable that China is experiencing an even greater decline than the Netherlands.
  • Regarding the volume of freight carried, it comes to the same conclusion. Both countries observe a decline when the COVID-19 pandemic begins in 2019. It is also remarkable that China is experiencing an even greater decline than the Netherlands.
  • The two curves for the containers flow are similar although with very different values. Indeed, their shape is comparable. The flow of containers has generally only increased. The covid had no major impact.
  • China's carbon dioxid emissions are on the rise. The appearance of covid has not changed this. In contrast, the Netherlands was already in a phase of decreasing CO2 emissions and the introduction of COVID-19 has not changed this trend.
  • Life expectancy is falling for the Netherlands. This is due to the additional deaths caused by covid. For China, life expectancy continues to increase in 2019. This is consistent with the low number of covid cases and therefore few (very few) COVID-19 deaths.
  • Both GDPs has descreased with the COVID-19's introduction. The decrease is somewhat greater for the Netherlands.

Although they have very few cases of COVID-19, China has generally experienced the same consequences of Covid as the Netherlands. Their economy and the behaviour of the different transport variables are in most cases similar to the behaviour observed in the Netherlands.

To go a step further, it is possible to use the Pearson correlation to better understand the dependencies between the different variables:

In [48]:
# Adding the graph

mask = np.triu(np.ones_like(df1.corr(), dtype=bool))
sns.heatmap(df1.corr(), mask=mask, annot=True) 
Out[48]:
<AxesSubplot:>

The first observation is that Dutch CO2 emissions are negatively related to other variables. Indeed, the curve is descending while the others are generally ascending. The rest of the variables are positively correlated and are relatively close to 1. This means that they tend to be dependent (the smallest positive value is 0.66).